home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Extra 1996 #3 / AmigaPlus_CD-ROM-EXTRA_Nr.3.bin / aminet-spiele / role on / larn / fortune.c < prev    next >
C/C++ Source or Header  |  1997-12-31  |  4KB  |  169 lines

  1. /* fortune.c */
  2. #ifdef VMS
  3. #include <types.h>
  4. #include <stat.h>
  5. #include <file.h>
  6. #else
  7. # include <sys/types.h>
  8. # include <sys/stat.h>
  9. # ifndef BSD4.1
  10. #  include <fcntl.h>
  11. # else BSD4.1
  12. # define O_RDONLY 0
  13. # endif BSD4.1
  14. #endif VMS
  15.  
  16. #include "header.h"
  17. #include "player.h"
  18. #include "larndefs.h"
  19. extern char fortfile[];
  20.  
  21. outfortune()
  22.     {
  23.     char *p;
  24.  
  25.     lprcat("\nThe cookie was delicious.");
  26.     if (c[BLINDCOUNT])
  27.         return;
  28. #ifdef MSDOS
  29.     msdosfortune();
  30. #else
  31.     if (p=fortune(fortfile))
  32.         {
  33.         lprcat("  Inside you find a scrap of paper that says:\n");
  34.         lprcat(p);
  35.         }
  36. #endif
  37.     }
  38.  
  39. # ifdef MSDOS
  40. # include <stdio.h>
  41. /* Rumors has been entirely rewritten to be disk based.  This is marginally
  42.  * slower, but requires no mallocked memory.  Notice this in only valid for
  43.  * files smaller than 32K.
  44.  */
  45. static int fortsize = 0;
  46.  
  47. static msdosfortune()
  48. {
  49.     int fd, status, i;
  50.     char    buf[BUFSIZ], ch;
  51.  
  52.     if (fortsize < 0)   /* We couldn't open fortunes */
  53.         return;
  54.     if ((fd = open(fortfile, O_RDONLY | O_BINARY)) >= 0) {
  55.         if (fortsize == 0)
  56.             fortsize = (int) lseek(fd, 0L, 2);
  57.         if (lseek(fd, (long) rund(fortsize), 0) < 0)
  58.             return;
  59.  
  60.         /* Skip to next newline or EOF
  61.          */
  62.         do {
  63.             status = read(fd, &ch, 1);
  64.         } while (status != EOF && ch != '\n');
  65.         if (status == EOF)
  66.             if (lseek(fd, 0L, 0) < 0) /* back to the beginning */
  67.                 return;
  68.  
  69.         /* Read in the line.  Search for CR ('\r'), not NL
  70.          */
  71.         for (i = 0; i < BUFSIZ - 1; i++)
  72.             if (read(fd, &buf[i], 1) == EOF || buf[i] == '\r')
  73.                 break;
  74.         buf[i] = '\0';
  75.  
  76.         /* And spit it out
  77.          */
  78.         lprcat("  Inside you find a scrap of paper that says:\n");
  79.         lprcat(buf);
  80.         close(fd);
  81.     } else
  82.         fortsize = -1;  /* Don't try opening it again */
  83. }
  84.  
  85. # else
  86.  
  87. /*
  88.  *  function to return a random fortune from the fortune file
  89.  */
  90. static char *base=0;    /* pointer to the fortune text */
  91. static char **flines=0; /* array of pointers to each fortune */
  92. static int fd=0;    /* true if we have load the fortune info */
  93. static int nlines=0;    /* # lines in fortune database */
  94.  
  95. static char *fortune(file)
  96. char *file;
  97. {
  98.     register char *p;
  99.     register int lines,tmp;
  100.     struct stat statbuf;
  101.     void *malloc();
  102.  
  103.     if (fd == 0) {
  104.         if ((fd=open(file,O_RDONLY)) < 0)   /* open the file */
  105.             return(0); /* can't find file */
  106.  
  107.         /* find out how big fortune file is and get memory for it */
  108.         statbuf.st_size = 16384;
  109. #ifdef AMIGA
  110.                 if((stat(file, &statbuf) < 0)
  111. #else
  112.         if((fstat(fd, &statbuf) < 0)
  113. #endif /* AMIGA */
  114.         || ((base=(char *)malloc(1+statbuf.st_size)) == 0)) {
  115.             close(fd);
  116.             fd= -1;
  117.             free((char*)base);
  118.             return(0);  /* can't stat file */
  119.         }
  120.  
  121.         /* read in the entire fortune file */
  122. #ifdef VMS
  123.         /*
  124.          * fstat lies about the size (each record has up to
  125.          * three bytes of fill reported as actual size).
  126.          * vread returns correct size.
  127.          */
  128.         statbuf.st_size = vread(fd,base,statbuf.st_size);
  129.         if (statbuf.st_size <= 0)
  130. #else
  131.         if (vread(fd,base,statbuf.st_size) != statbuf.st_size)
  132. #endif
  133.         {
  134.             close(fd);
  135.             fd= -1;
  136.             free((char*)base);
  137.             return(0);  /* can't read file */
  138.         }
  139.         close(fd);
  140.         base[statbuf.st_size]=0;   /* final NULL termination */
  141.  
  142.         /* count up all the lines (and 0 terminate) to know memory
  143.          * needs
  144.          */
  145.         for (p=base,lines=0; p<base+statbuf.st_size; p++) /* count lines */
  146.             if (*p == '\n') *p=0,lines++;
  147.         nlines = lines;
  148.  
  149.         /* get memory for array of pointers to each fortune */
  150.         if ((flines=(char**)malloc(nlines*sizeof(char*))) == 0) {
  151.             free((char*)base);
  152.             fd= -1;
  153.             return(0); /* malloc() failure */
  154.         }
  155.  
  156.         /* now assign each pointer to a line */
  157.         for (p=base,tmp=0; tmp<nlines; tmp++)
  158.             {
  159.             flines[tmp]=p;  while (*p++); /* advance to next line */
  160.             }
  161.     }
  162.  
  163.     if (fd > 2) /* if we have a database to look at */
  164.         return(flines[rund((nlines<=0)?1:nlines)]);
  165.     else
  166.         return(0);
  167. }
  168. # endif
  169.